//
//  UIViewController+NavigationBar.m
//  KKNavigationBarDemo
//
//  Created by liaozhenming on 2016/12/23.
//  Copyright © 2016年 liaozhenming. All rights reserved.
//

#import "UIViewController+NavigationBar.h"
#import <objc/runtime.h>

@interface KKNavigationBar_Manager : NSObject
+ (instancetype)sharedInstance;

@property (nonatomic, assign) BOOL isRegistered;    /**<是否已经注册了*/
@property (nonatomic, assign) BOOL isSuppor;        /**<是否支持自定义bar颜色*/
@property (nonatomic, strong) UIImage *shadowImage;
@property (nonatomic, strong) UIView *overlay;
@end

@implementation KKNavigationBar_Manager

+ (instancetype)sharedInstance {
    static KKNavigationBar_Manager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self class] new];
    });
    return manager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.isRegistered = false;
        self.isSuppor = false;
        self.overlay = [[UIView alloc] initWithFrame: CGRectMake(0, -20, CGRectGetWidth([[UIScreen mainScreen] bounds]), 64)];
        self.overlay.userInteractionEnabled = false;
    }
    return self;
}

@end

#pragma mark - UINavigationBar

@interface UINavigationBar(BarColor)

- (void)kk_initBarColorLayer;

@end

@implementation UINavigationBar(BarColor)

- (void)kk_initBarColorLayer {
    
    KKNavigationBar_Manager *manager = [KKNavigationBar_Manager sharedInstance];
    manager.shadowImage = self.shadowImage;
    
    if (manager.isSuppor == YES) {
        [self setBackgroundImage: [UIImage new] forBarMetrics: UIBarMetricsDefault];
        NSArray *selfSubViews = self.subviews;
        UIView *targetView = [selfSubViews firstObject];
        
        if (CGRectGetMinY(targetView.frame) == -20.0 && CGRectGetHeight(targetView.frame) == 64) {
            manager.overlay.frame = targetView.bounds;
        }
        else if (CGRectGetMinY(targetView.frame) == 0.0 && CGRectGetHeight(targetView.frame) == 44) {
            manager.overlay.frame = CGRectMake(0, 0, CGRectGetWidth(targetView.frame), 64);
        }
        [targetView addSubview: manager.overlay];
    }
    else {
        [manager.overlay removeFromSuperview];
    }
}

- (void)kk_cleanBarColorLayer {
    KKNavigationBar_Manager *manager = [KKNavigationBar_Manager sharedInstance];
    [manager.overlay removeFromSuperview];
}

@end

#pragma mark -

@implementation UIViewController (NavigationBar)

static NSString *UIViewControllerNavigationBarColorValue = @"UIViewControllerNavigationBarColorValue";
static NSString *UIViewControllerNavigationBarAlphaValue = @"UIViewControllerNavigationBarAlphaValue";

static const void *UIViewControllerNavigationBarInfoValue = &UIViewControllerNavigationBarInfoValue;
- (void)kk_saveCurrentNavigationBarInfo:(NSDictionary*)barInfo {
    objc_setAssociatedObject(self, UIViewControllerNavigationBarInfoValue, barInfo, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSDictionary*)kk_barInfo {
    return objc_getAssociatedObject(self, UIViewControllerNavigationBarInfoValue);
}


+ (void)load {
    Method viewWillAppear = class_getInstanceMethod([self class], NSSelectorFromString(@"viewWillAppear:"));
    Method kk_viewWillAppear = class_getInstanceMethod([self class], @selector(kk_viewWillAppear:));
    method_exchangeImplementations(viewWillAppear, kk_viewWillAppear);
    
    Method viewWillDisappear = class_getInstanceMethod([self class], NSSelectorFromString(@"viewWillDisappear:"));
    Method kk_viewWillDisappear = class_getInstanceMethod([self class], @selector(kk_viewWillDisappear:));
    method_exchangeImplementations(viewWillDisappear, kk_viewWillDisappear);
}

- (void)kk_viewWillAppear:(BOOL)animated {
    [self kk_viewWillAppear: animated];
    [self kk_setNavigationBarBackgroundColor: [self kk_currentBarColor] alpha:[self kk_currentBarAlpha]];
}

- (void)kk_viewWillDisappear:(BOOL)animated {
    [self kk_viewWillDisappear: animated];
}

#pragma mark - Public methods
+ (void)kk_registerCustomizedNavigationBar {
    
    if ([KKNavigationBar_Manager sharedInstance].isSuppor == NO) {
        [KKNavigationBar_Manager sharedInstance].isSuppor = YES;
    }
}

- (void)kk_setNavigationBarBackgroundColor:(UIColor *)backgroundColor {
    [self kk_setNavigationBarBackgroundColor: backgroundColor alpha: 1.0];
}

- (void)kk_setNavigationBarBackgroundColor:(UIColor *)backgroundColor alpha:(CGFloat)alpha {
    if (backgroundColor == nil || self.navigationController == nil) {
        [self.navigationController.navigationBar kk_cleanBarColorLayer];
        return;
    }
    
    if ([KKNavigationBar_Manager sharedInstance].isSuppor == YES && [KKNavigationBar_Manager sharedInstance].isRegistered == NO) {
        [KKNavigationBar_Manager sharedInstance].isRegistered = YES;
        [self.navigationController.navigationBar kk_initBarColorLayer];
    }
    
    [self kk_saveCurrentNavigationBarInfo:@{UIViewControllerNavigationBarColorValue:backgroundColor,UIViewControllerNavigationBarAlphaValue:@(alpha)}];
    
    if (alpha < 1.0) {
        self.navigationController.navigationBar.shadowImage = [UIImage new];
    }
    else {
        self.navigationController.navigationBar.shadowImage = [KKNavigationBar_Manager sharedInstance].shadowImage;
    }
    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
    
    UIColor *barColor = [backgroundColor colorWithAlphaComponent: alpha];
    [KKNavigationBar_Manager sharedInstance].overlay.backgroundColor = barColor;
}

- (UIColor*)kk_currentBarColor {
    NSDictionary *barInfo = [self kk_barInfo];
    UIColor *barColor = barInfo[UIViewControllerNavigationBarColorValue];
    return barColor;
}

- (CGFloat)kk_currentBarAlpha {
    NSDictionary *barInfo = [self kk_barInfo];
    NSNumber *alphaValue = barInfo[UIViewControllerNavigationBarAlphaValue];
    return alphaValue.floatValue;
}

- (void)kk_updateNavigationBarBackgroundColorWithAlpha:(CGFloat)alpha {
    [self kk_setNavigationBarBackgroundColor: [self kk_currentBarColor] alpha: alpha];
}
@end
